/***************************************************************************
 *   Copyright (C) 2009 by Geoffrey McRae   *
 *   geoff@spacevs.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef _H_LINKED_LISTS_
#define _H_LINKED_LISTS_
#include "../mediaplayer.h"

/* thread safe linked list functions */
typedef	void (*ll_func_destroy)(void* data);
typedef bool (*ll_func_foreach)(void* data, bool *remove, void* loop_data);
typedef struct ll_item	ll_item_t;
typedef struct ll	ll_t;

/* Create a new linked list, optional destroy function for the contained data, limited to the specified size (0 = unlimited) */
ll_t* ll_new(ll_func_destroy f_destroy, unsigned int limit);

/* Free the linked list */
void ll_free(ll_t *ll);

/* Empty the linked list */
void ll_empty(ll_t *ll);

/* Push a new item onto the end of the list */
void ll_push(ll_t *ll, void *data);

/* Shift an item off the front of the list */
void* ll_shift(ll_t *ll);

/* Pop an item off the front of the list */
void* ll_pop(ll_t *ll);

/* Unshift an item onto the front of the list */
void ll_unshift(ll_t *ll, void *data);

/* insert an item into the list */
void ll_insert_after(ll_t *ll, void *after, void *data, bool lock);

/* Itterate the items in the list */
bool ll_foreach(ll_t *ll, bool reverse, ll_func_foreach f_foreach, void *loop_data);

/* Return the number of items in the ll */
inline unsigned int ll_size(ll_t *ll);

/* Return if the ll is empty */
inline bool ll_isempty(ll_t *ll);

/* shift left one and return the first element (runs in a circle) */
inline void* ll_next(ll_t *ll);

/* Tell the ll that we want to drain its contents and not block when empty */
inline void ll_drain(ll_t *ll);

/* Tell the ll to plug the drain again */
inline void ll_plug(ll_t *ll);
#endif

